package org.example.domain.dto;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.Collections;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;

@Data
@NoArgsConstructor
@AllArgsConstructor
@ApiModel(description = "分页结果")
public class PageDTO<V> {
    @ApiModelProperty("总条数")
    private Long total;
    @ApiModelProperty("总页数")
    private Long pages;
    @ApiModelProperty("当前页数")
    private Long current;
    @ApiModelProperty("每页显示条数")
    private Long size;
    @ApiModelProperty("集合")
    private List<V> records;
    
    /**
     * 返回空分页结果
     * @param p MyBatisPlus的分页结果
     * @return VO的分页对象
     * @param <V> 目标VO类型
     * @param <P> 目标PO类型
     */
    public static <V, P> PageDTO<V> empty(Page<P> p) {
        return new PageDTO<>(p.getTotal(), p.getPages(), p.getCurrent(), p.getSize(), Collections.emptyList());
    }
    
    /**
     * 将MyBatisPlus分页结果转为VO分页结果
     * @param p MyBatisPlus的分页结果
     * @param clazz 目标VO类型的字节码
     * @param <PO> 原始PO类型
     * @param <VO> 目标VO类型
     * @return VO的分页对象
     */
    public static <PO, VO> PageDTO<VO> of(Page<PO> p, Class<VO> clazz) {
        // 3.封装VO结果
        PageDTO<VO> dto = new PageDTO<>();
        // 3.1.总条数
        dto.setTotal(p.getTotal());
        // 3.2.总页数
        dto.setPages(p.getPages());
        // 3.3.当前页数据
        List<PO> records = p.getRecords();
        // 3.4.当前页数
        dto.setCurrent(p.getCurrent());
        // 3.5.当前页显示条数
        dto.setSize(p.getSize());
        if (CollUtil.isEmpty(records)) {
            dto.setRecords(Collections.emptyList());
            return dto;
        }
        // 3.4.拷贝VO
        dto.setRecords(BeanUtil.copyToList(records, clazz));
        return dto;
    }
    
    /**
     * 将MyBatisPlus分页结果转为VO分页结果,允许自定义PO到VO的转换方式
     * @param p MyBatisPlus的分页结果
     * @param <PO> 原始PO类型
     * @param <VO> 目标VO类型
     * @return VO的分页对象
     */
    public static <PO, VO> PageDTO<VO> of(Page<PO> p, Function<PO, VO> convertor) {
        // 3.封装VO结果
        PageDTO<VO> dto = new PageDTO<>();
        // 3.1.总条数
        dto.setTotal(p.getTotal());
        // 3.2.总页数
        dto.setPages(p.getPages());
        // 3.3.当前页数据
        List<PO> records = p.getRecords();
        // 3.4.当前页数
        dto.setCurrent(p.getCurrent());
        // 3.5.当前页显示条数
        dto.setSize(p.getSize());
        if (CollUtil.isEmpty(records)) {
            dto.setRecords(Collections.emptyList());
            return dto;
        }
        // 3.4.拷贝user的VO
        dto.setRecords(records.stream().map(convertor).collect(Collectors.toList()));
        
        // 4.返回
        return dto;
    }
}
